package the.broccoli.setting.interfaces.controller;

import io.swagger.annotations.ApiParam;
import org.apache.commons.lang.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.wisteria.framework.web.APIResult;
import org.wisteria.framework.web.QueryResult;
import org.wisteria.framework.web.mvc.constant.WebConsts;
import org.wisteria.framework.web.mvc.dto.TreeDTO;
import the.broccoli.auth.UserContext;
import the.broccoli.setting.entity.Dict;
import the.broccoli.setting.service.IDictService;
import the.broccoli.setting.dto.DictCondition;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 字典项控制器
 *
 * @author lei.liu
 * @since 2019-11-27 16:56:32
 */
@RestController
@RequestMapping("/setting/dict")
public class DictController {

    @Autowired
    private IDictService dictService;

    @PostMapping("/add")
    public APIResult add(
            @ApiParam(name = "parentId", value = "父级字典项ID", required = false)
            @RequestParam(value = "parentId", required = false) String parentId,
            @ApiParam(name = "dictName", value = "字典项名称", required = true)
            @RequestParam(value = "dictName", required = true) String dictName,
            @ApiParam(name = "serial", value = "序号", required = false)
            @RequestParam(value = "serial", required = false) Integer serial,
            @ApiParam(name = "dictValue", value = "扩展值", required = false)
            @RequestParam(value = "dictValue", required = false) String dictValue,
            @ApiParam(name = "constant", value = "代码", required = false)
            @RequestParam(value = "constant", required = false) String constant
    ) {
        if (!StringUtils.hasText(parentId)) {
            parentId = WebConsts.ROOT;
        }

        Dict entity = new Dict();
        entity.setConstant(constant);
        entity.setParentId(parentId);
        entity.setDictCode(newDictCode(parentId));
        entity.setDictName(dictName);
        entity.setDictValue(dictValue);
        entity.setSerial(serial);
        entity.setIsDeleted(0);
        entity.setCreatedId(UserContext.userId());
        entity.setCreatedName(UserContext.userName());
        entity.setCreatedTime(new Date());
        dictService.save(entity);
        return APIResult.success();
    }

    @PostMapping("/remove")
    public APIResult remove(@RequestParam(value = "ids", required = true) List<String> ids) {
        dictService.removeByIds(ids, UserContext.userId(), UserContext.userName());
        return APIResult.success();
    }

    @PostMapping("/modify")
    public APIResult modify(
            @ApiParam(name = "dictId", value = "字典项ID", required = true)
            @RequestParam(value = "dictId", required = true) String dictId,
            @ApiParam(name = "serial", value = "序号", required = false)
            @RequestParam(value = "serial", required = false) Integer serial,
            @ApiParam(name = "dictName", value = "字典项名称", required = true)
            @RequestParam(value = "dictName", required = true) String dictName,
            @ApiParam(name = "dictValue", value = "字典项值", required = true)
            @RequestParam(value = "dictValue", required = true) String dictValue,
            @ApiParam(name = "dictExt", value = "字典项扩展值", required = false)
            @RequestParam(value = "dictExt", required = false) String dictExt
    ) {
        Dict entity = new Dict();
        entity.setDictId(dictId);
        entity.setDictName(dictName);
        entity.setDictValue(dictValue);
        entity.setSerial(serial);
        entity.setModifiedId(UserContext.userId());
        entity.setModifiedName(UserContext.userName());
        entity.setModifiedTime(new Date());
        dictService.updateById(entity);
        return APIResult.success();
    }

    @GetMapping("/{dictId}")
    public APIResult get(@ApiParam(name = "dictId", value = "字典项ID", required = true) @PathVariable(value = "dictId") String dictId) {
        return APIResult.success(dictService.getById(dictId));
    }

    @GetMapping("/page")
    public APIResult<QueryResult> page(
            @ApiParam(name = "parentId", value = "父ID", required = false)
            @RequestParam(value = "parentId", required = false) String parentId,
            @ApiParam(name = "keyword", value = "关键字", required = false)
            @RequestParam(value = "keyword", required = false) String keyword,
            @ApiParam(name = "orderBy", value = "排序字段", required = false)
            @RequestParam(value = "orderBy", required = false) String orderBy,
            @ApiParam(name = "pageNum", value = "页码", required = false, defaultValue = "1")
            @RequestParam(value = "pageNum", required = false) Integer pageNum,
            @ApiParam(name = "pageNum", value = "每页大小", required = false, defaultValue = "20")
            @RequestParam(value = "pageSize", required = false) Integer pageSize
    ) {
        DictCondition condition = new DictCondition();
        condition.setParentId(parentId);
        condition.setKeyword(keyword);
        condition.setOrderBy(orderBy);
        return APIResult.success(dictService.pageList(condition, pageNum, pageSize));
    }

    @GetMapping("/tree")
    public APIResult<List<TreeDTO>> getTree() {
        List<TreeDTO> treeList = new ArrayList<>();
        TreeDTO treeDTO = new TreeDTO();
        treeDTO.setTitle(WebConsts.ROOT);
        treeDTO.setId(WebConsts.ROOT);
        treeDTO.setChildren(dictService.getTree());
        treeList.add(treeDTO);
        return APIResult.success(treeList);
    }

    @GetMapping("/multi/{constant}/{level}")
    public APIResult<List<TreeDTO>> getMulti(
            @ApiParam(name = "constant", value = "代码", required = true)
            @PathVariable(value = "constant") String constant,

            @PathVariable(value = "level") Integer level
    ) {
        DictCondition condition = new DictCondition();
        condition.setConstant(constant);
        condition.setLevel(level);
        return APIResult.success(dictService.getTree(condition));
    }

    @GetMapping("/list/constant/{constant}")
    public APIResult getDictListByConstant(@ApiParam(name = "constant", value = "代码", required = true) @PathVariable(value = "constant") String constant) {
        List<Dict> data = null;
        DictCondition condition = new DictCondition();
        condition.setConstant(constant);
        condition.setParentId(WebConsts.ROOT);
        List<Dict> dictList = dictService.listByCondition(condition);
        if (!CollectionUtils.isEmpty(dictList)) {
            data = getDictListByParentId(dictList.get(0).getDictId());
        }
        return APIResult.success(data);
    }

    @GetMapping("/list/parent-code/{parentCode}")
    public APIResult getDictListByParentCode(
            @ApiParam(name = "parentCode", value = "父级编码", required = true) @PathVariable(value = "parentCode") String parentCode
    ) {
        List<Dict> data = null;
        Dict entity = dictService.getByCode(parentCode);
        if (entity != null) {
            data = getDictListByParentId(entity.getDictId());
        }
        return APIResult.success(data);
    }

    @GetMapping("/list/parent-id/{parentId}")
    public APIResult dictListByParentId(@ApiParam(name = "parentId", value = "父级ID", required = true) @PathVariable(value = "parentId") String parentId) {
        return APIResult.success(getDictListByParentId(parentId));
    }

    private List<Dict> getDictListByParentId(String parentId) {
        DictCondition condition = new DictCondition();
        condition.setParentId(parentId);
        return dictService.listByCondition(condition);
    }

    private String newDictCode(String parentId) {
        List<Dict> dictList = getDictListByParentId(parentId);
        if (CollectionUtils.isEmpty(dictList)) {
            Dict parentDict = dictService.getById(parentId);
            if (parentDict != null && StringUtils.hasText(parentDict.getDictCode())) {
                return parentDict.getDictCode() + "01";
            }
        } else {
            Integer maxCode = null;
            String maxDictCode = null;
            for (Dict dict : dictList) {
                String code = dict.getDictCode();
                if (NumberUtils.isNumber(code)) {
                    int codeInt = Integer.valueOf(code);
                    if (maxCode == null || maxCode < codeInt) {
                        maxDictCode = code;
                        maxCode = codeInt;
                    }
                }
            }

            if (StringUtils.hasText(maxDictCode)) {
                int intDictCode = maxCode + 1;
                return maxDictCode.indexOf("0") == 0 ? "0" + intDictCode : intDictCode + "";
            }
        }
        return "01";
    }
}